package com.chb.docter.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.chb.docter.dto.*;
import com.chb.docter.feigns.DeptFeign;
import com.chb.docter.feigns.MedicinesFeign;
import com.chb.docter.feigns.UserFeign;
import com.chb.docter.mapper.*;
import com.chb.docter.params.CareOrderParam;
import com.chb.docter.service.CareHistoryService;
import com.hos.entity.his.*;
import com.hos.entity.stock.Medicines;
import com.hos.entity.sys.Dept;
import com.hos.entity.sys.User;
import com.hos.utils.IdGeneratorUtil;
import com.hos.utils.WebUtil;
import com.hos.vo.Result;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

/**
 * @author: 陈海彬
 * @date: Created in 2023/12/14 10:24
 * @description:
 * @modified By:
 * @version:
 */
@Service
@Slf4j
public class CareHistoryServiceImpl implements CareHistoryService {

    @Resource
    private CareHistoryMapper careHistoryMapper;
    @Resource
    private PatientMapper patientMapper;
    @Resource
    private PatientFileMapper patientFileMapper;
    @Resource
    private UserFeign userFeign;
    @Resource
    private DeptFeign deptFeign;
    @Resource
    private CareOrderMapper careOrderMapper;
    @Resource
    private CareOrderItemMapper careOrderItemMapper;
    @Resource
    private MedicinesFeign medicinesFeign;
    @Resource
    private RegistrationMapper registrationMapper;
    @Resource
    private CheckResultMapper checkResultMapper;
    @Autowired
    private StringRedisTemplate redisTemplate;

    @Override
    public Result<PatientAndCareHistoryDto> getPatientAllMessageByPatientId(String patientId) {
        // 1.查询患者信息
        Patient patient = this.patientMapper.selectById(patientId);

        // 2.查询历史病例
        LambdaQueryWrapper<CareHistory> careWrapper = new LambdaQueryWrapper<>();
        careWrapper.eq(CareHistory::getPatientId, patientId);
        List<CareHistory> careHistories = this.careHistoryMapper.selectList(careWrapper);

        // 3.查询档案信息
        PatientFile patientFile = this.patientFileMapper.selectById(patientId);

        return new Result<>(200, "查询成功",
                new PatientAndCareHistoryDto(patient, careHistories, patientFile));
    }

    @Override
    public CareHistory getCareHistoryByRegId(String regId) {
        LambdaQueryWrapper<CareHistory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CareHistory::getRegId, regId);
        CareHistory careHistory = this.careHistoryMapper.selectOne(wrapper);

        Registration registration = this.registrationMapper.selectById(regId);
        careHistory.setStatus(registration.getRegistrationStatus());

        return careHistory;
    }

    @Override
    public CareHistory saveCareHistory(CareHistory careHistory) {
        // 判断进行添加或者修改
        if (StringUtils.hasText(careHistory.getChId())) {
            // 进行修改
            int i = this.careHistoryMapper.updateById(careHistory);
            if (i > 0) {
                return careHistory;
            }
        } else {
            User user = getUserByToken();
            // 1.设置医生id  医生姓名
            careHistory.setUserId(user.getUserId());
            careHistory.setUserName(user.getUserName());
            // 2.设置科室id 科室名称
            Dept dept = deptFeign.selectDeptByDeptId(user.getDeptId());
            careHistory.setDeptName(dept.getDeptName());
            careHistory.setDeptId(dept.getDeptId());
            // 3.设置创建时间
            careHistory.setCareTime(new Date());
            // 4.设置病例Id
            String chId = IdGeneratorUtil.nextId("CH");
            careHistory.setChId(chId);
            // 进行保存病例
            int index = this.careHistoryMapper.insert(careHistory);
            if (index > 0) {
                return careHistory;
            }
        }
        return null;
    }

    @Override
    public void saveCareOrderItem(CareOrderParam careOrderParam) {
        User user = getUserByToken();
        // 判断是否为重复添加药方
        CareOrder careOrder = careOrderParam.getCareOrder();
        LambdaQueryWrapper<CareOrder> firstWrapper = new LambdaQueryWrapper<>();
        firstWrapper.eq(CareOrder::getChId, careOrder.getChId())
                .eq(CareOrder::getCoType, careOrder.getCoType());
        CareOrder order = this.careOrderMapper.selectOne(firstWrapper);
        if (order != null) {
            // 修改价格
            // 进行总价的相加
            // 修改处方药品信息
            order.setAllAmount(order.getAllAmount().add(careOrder.getAllAmount()));
            order.setUpdateBy(user.getUserName());
            order.setUpdateTime(new Date());
            this.careOrderMapper.updateById(order);
            // 拿到coId
            String coId = order.getCoId();
            // 判断是否有相同的药品
            List<CareOrderItem> orderItems = careOrderParam.getCareOrderItems();

            for (CareOrderItem orderItem : orderItems) {
                LambdaQueryWrapper<CareOrderItem> careOrderItemLambdaQueryWrapper = new LambdaQueryWrapper<>();
                careOrderItemLambdaQueryWrapper.eq(CareOrderItem::getCoId, coId)
                        .eq(CareOrderItem::getItemRefId, orderItem.getItemRefId());
                CareOrderItem careOrderItem = this.careOrderItemMapper.selectOne(careOrderItemLambdaQueryWrapper);
                if (careOrderItem != null) {
                    // 进行修改价格
                    careOrderItem.setNum(orderItem.getNum().add(careOrderItem.getNum()));
                    careOrderItem.setAmount(orderItem.getAmount().add(careOrderItem.getAmount()));
                    this.careOrderItemMapper.updateById(careOrderItem);
                } else {
                    // 进行添加处方药品信息
                    String itemId = IdGeneratorUtil.nextId("ITEM");
                    orderItem.setItemId(itemId);
                    orderItem.setCoId(order.getCoId());
                    orderItem.setStatus("0");
                    orderItem.setCreateTime(new Date());
                    this.careOrderItemMapper.insert(orderItem);
                    // 进行减少库存
                    // Medicines medicines = new Medicines();
//                     int num = Integer.parseInt(orderItem.getNum().toString());
                    // medicines.setMedicinesStockNum(num);
                    // medicines.setMedicinesId(Long.valueOf(orderItem.getItemRefId()));
//                     medicinesFeign.reducePharmaceuticalById(medicines);
                }
            }


        } else {
            // 进行创建药用订单
            String coId = IdGeneratorUtil.nextId("CO");
            careOrder.setCoId(coId);
            careOrder.setUserId(user.getUserId());
            careOrder.setCreateTime(new Date());
            careOrder.setCreateBy(user.getUserName());
            // 1.创建药用处方
            this.careOrderMapper.insert(careOrder);
            // 2.创建开诊细表
            List<CareOrderItem> orderItems = careOrderParam.getCareOrderItems();
            if (orderItems.size() > 0) {
                for (CareOrderItem orderItem : orderItems) {
                    String itemId = IdGeneratorUtil.nextId("ITEM");
                    orderItem.setItemId(itemId);
                    orderItem.setCoId(careOrder.getCoId());
                    orderItem.setStatus("0");
                    orderItem.setCreateTime(new Date());
                    this.careOrderItemMapper.insert(orderItem);
                    // 进行减少库存
                    // Medicines medicines = new Medicines();
                    // int num = Integer.parseInt(orderItem.getNum().toString());
                    // medicines.setMedicinesStockNum(num);
                    // medicines.setMedicinesId(Long.valueOf(orderItem.getItemRefId()));
                    // medicinesFeign.reducePharmaceuticalById(medicines);
                }
            }
        }
    }

    @Override
    public List<CareOrderDto> queryCareOrdersByChId(String chId) {
        // 1.查询药用处方的内容
        LambdaQueryWrapper<CareOrder> careOrderLambdaQueryWrapper = new LambdaQueryWrapper<>();
        careOrderLambdaQueryWrapper.eq(CareOrder::getChId, chId);
        List<CareOrder> orders = this.careOrderMapper.selectList(careOrderLambdaQueryWrapper);
        if (orders.size() > 0) {
            List<CareOrderDto> careOrderDtos = new ArrayList<>();
            for (CareOrder order : orders) {
                LambdaQueryWrapper<CareOrderItem> careOrderItemLambdaQueryWrapper = new LambdaQueryWrapper<>();
                careOrderItemLambdaQueryWrapper.eq(CareOrderItem::getCoId, order.getCoId());
                List<CareOrderItem> careOrderItems = this.careOrderItemMapper.selectList(careOrderItemLambdaQueryWrapper);
                careOrderDtos.add(new CareOrderDto(order, careOrderItems));
            }
            return careOrderDtos;
        }
        return null;
    }

    @Override
    public void visitComplete(String regId) {
        LambdaUpdateWrapper<Registration> wrapper = new LambdaUpdateWrapper<>();
        wrapper.eq(Registration::getRegistrationId, regId)
                .set(Registration::getRegistrationStatus, 3)
                .set(Registration::getUpdateTime, new Date());
        this.registrationMapper.update(wrapper);
    }

    @Override
    public void deleteCareOrderItemById(String itemId) {
        LambdaQueryWrapper<CareOrderItem> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CareOrderItem::getItemId, itemId)
                .eq(CareOrderItem::getStatus, 0);
        CareOrderItem orderItem = this.careOrderItemMapper.selectOne(wrapper);
        if (orderItem == null) {
            throw new RuntimeException("请传入正确的处方详情id");
        }
        if ("0".equals(orderItem.getItemType())) {
            // 进行回退药品数量
            Medicines medicines = new Medicines();
            medicines.setMedicinesStockNum(orderItem.getNum().intValue());
            medicines.setMedicinesId(Long.valueOf(orderItem.getItemRefId()));
            this.medicinesFeign.addPharmaceuticalById(medicines);
        }
        // 回退金额
        BigDecimal price = orderItem.getPrice();
        LambdaQueryWrapper<CareOrder> careOrderLambdaQueryWrapper = new LambdaQueryWrapper<>();
        careOrderLambdaQueryWrapper.eq(CareOrder::getCoId, orderItem.getCoId());
        CareOrder careOrder = this.careOrderMapper.selectOne(careOrderLambdaQueryWrapper);
        // 减去金额
        careOrder.setAllAmount(careOrder.getAllAmount().subtract(price));
        careOrder.setUpdateTime(new Date());
        careOrder.setUpdateBy(getUserByToken().getUserName());
        this.careOrderMapper.updateById(careOrder);
        // 删除该药品信息
        this.careOrderItemMapper.deleteById(itemId);
    }

    @Override
    public OrderDetailsDto getRegistrationListByChId(String chId) {
        OrderDetailsDto orderDetailsDto = new OrderDetailsDto();

        // 1.设置处方列表
        List<CareOrderDto> careOrderDtos = this.queryCareOrdersByChId(chId);
        List<CareOrderItem> orderItems = careOrderDtos.get(0).getCareOrderItems();
        for (CareOrderItem orderItem : orderItems) {
            // 4.设置订单状态
            String status = orderItem.getStatus();
            switch (status) {
                case "0":
                    orderDetailsDto.setOrderStatus(1);
                    break;
                case "1":
                    orderDetailsDto.setOrderStatus(4);
                    break;
                case "3":
                    orderDetailsDto.setOrderStatus(5);
                    break;
                case "5":
                    orderDetailsDto.setOrderStatus(6);
                    break;
                default:
                    orderDetailsDto.setOrderStatus(0);
                    break;
            }
        }
        orderDetailsDto.setCareOrderDtos(careOrderDtos);
        // 2.查询病例详情
        CareHistory careHistory = this.careHistoryMapper.selectById(chId);
        orderDetailsDto.setCareHistory(careHistory);
        // 3.查询总价
        LambdaQueryWrapper<CareOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CareOrder::getChId, chId);
        List<CareOrder> orders = this.careOrderMapper.selectList(wrapper);
        // 设置总价
        orderDetailsDto.setTotalMoney(orders.stream().map(CareOrder::getAllAmount).reduce(BigDecimal.ZERO, BigDecimal::add));


        // 4.设置订单状态
        // Registration registration = this.registrationMapper.selectById(careHistory.getRegId());
        // String status = registration.getRegistrationStatus();
        // if ("3".equals(status)) {
        //     orderDetailsDto.setOrderStatus(1);
        // }
        return orderDetailsDto;
    }

    @Override
    public List<CareOrder> getCareOrderListByCoType() {
        // 1.查询检查处方列表
        List<CareOrder> careOrders = this.getCareOrderListByCoType("1");
        for (CareOrder careOrder : careOrders) {
            LambdaQueryWrapper<CareOrderItem> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(CareOrderItem::getCoId, careOrder.getCoId());
            // 2.查询检查处方子项列表
            List<CareOrderItem> orderItems = this.careOrderItemMapper.selectList(wrapper);
            for (CareOrderItem orderItem : orderItems) {
                CheckResult checkResult = this.checkResultMapper.selectById(orderItem.getItemId());
                orderItem.setStatus("0");
                if (checkResult != null) {
                    if ("1".equals(checkResult.getResultStatus())) {
                        orderItem.setStatus("1");
                    }
                }

            }
            careOrder.setCareOrderItems(orderItems);
        }
        return careOrders;
    }

    @Override
    public CheckOrderDetail getCheckOrderDetailsByItemId(String itemId) {
        CareOrderItem careOrderItem = this.careOrderItemMapper.selectById(itemId);
        CheckResult checkResult = this.checkResultMapper.selectById(itemId);
        return new CheckOrderDetail(careOrderItem, checkResult);
    }

    @Override
    public List<CareHistoryDto> getCareHistoryListByStatus(String orderState) {
        List<CareHistoryDto> returnDto = new ArrayList<>();
        // 1.查询病例列表
        List<CareHistory> careHistories = this.selectCareHistoryList();
        for (CareHistory careHistory : careHistories) {
            CareHistoryDto careHistoryDto = new CareHistoryDto();
            // 2.查询处方列表
            List<CareOrder> careOrderList = this.selectCareOrderList(careHistory.getChId());
            careHistory.setCareOrders(careOrderList);
            for (CareOrder careOrder : careOrderList) {
                // 3.查询子项---根据状态
                LambdaQueryWrapper<CareOrderItem> wrapper = new LambdaQueryWrapper<>();
                // 进行按条件查询
                if (!"4".equals(orderState)) {
                    wrapper.eq(CareOrderItem::getStatus, orderState);
                }
                wrapper.eq(CareOrderItem::getCoId, careOrder.getCoId());
                List<CareOrderItem> orderItems = this.careOrderItemMapper.selectList(wrapper);
                careOrder.setCareOrderItems(orderItems);
                if (orderItems.size() > 0) {

                    careHistoryDto.setCareOrder(careOrder);
                    careHistoryDto.setCareHistory(careHistory);
                }
            }
            returnDto.add(careHistoryDto);
        }
        return returnDto;
    }

    /**
     * @return java.util.List<com.hos.entity.his.CareOrder>
     * @create by: 陈海彬
     * @description: 查询患者处方列表
     * @create time: 2023/12/28 11:56
     */
    private List<CareOrder> selectCareOrderList(String chId) {
        LambdaQueryWrapper<CareOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CareOrder::getChId, chId);
        return this.careOrderMapper.selectList(wrapper);
    }

    /**
     * @return java.util.List<com.hos.entity.his.CareHistory>
     * @create by: 陈海彬
     * @description: 查询病例列表
     * @create time: 2023/12/28 11:53
     */
    private List<CareHistory> selectCareHistoryList() {
        LambdaQueryWrapper<CareHistory> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CareHistory::getPatientId, this.getPatientToken().getPatientId());
        return this.careHistoryMapper.selectList(wrapper);
    }

    @Override
    public Patient getAppPatientToken() {
        String token = WebUtil.getToken();
        String phone = redisTemplate.opsForValue().get("user:" + token);
        LambdaQueryWrapper<Patient> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Patient::getPhone, phone);
        Patient patient = this.patientMapper.selectOne(wrapper);
        patient.setPassword("");
        return patient;
    }


    /**
     * @param coType 处方类型
     * @return java.util.List<com.hos.entity.his.CareOrder>
     * @create by: 陈海彬
     * @description: 根据处方状态查询处方列表信息
     * @create time: 2023/12/26 19:21
     */
    private List<CareOrder> getCareOrderListByCoType(String coType) {
        Patient patient = getPatientToken();
        LambdaQueryWrapper<CareOrder> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(CareOrder::getPatientId, patient.getPatientId())
                .eq(CareOrder::getCoType, coType)
                .orderByDesc(CareOrder::getCreateTime);
        return this.careOrderMapper.selectList(wrapper);
    }

    /**
     * @return com.hos.entity.sys.User
     * @create by: 陈海彬
     * @description: 获取请求用户的信息
     * @create time: 2023/12/12 10:39
     */
    private Patient getPatientToken() {
        String token = WebUtil.getToken();
        String phone = redisTemplate.opsForValue().get("user:" + token);
        LambdaQueryWrapper<Patient> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(Patient::getPhone, phone);
        Patient patient = this.patientMapper.selectOne(wrapper);
        patient.setPassword("");
        return patient;
    }

    /**
     * @return com.hos.entity.sys.User
     * @create by: 陈海彬
     * @description: 获取请求用户的信息
     * @create time: 2023/12/12 10:39
     */
    private User getUserByToken() {
        String token = WebUtil.getToken();
        String phone = redisTemplate.opsForValue().get("user:" + token);
        return userFeign.selectUserByPhone(phone);
    }
}